package org.yn.auth.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.yn.auth.annotation.PermissionAnnotation;
import org.yn.auth.domain.Permission;
import org.yn.auth.mapper.PermissionMapper;
import org.yn.auth.service.IPermissionScanService;
import org.yn.base.enums.RequestTypeEnum;
import org.yn.base.util.ClassUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Service
public class PermissionScanServiceImpl implements IPermissionScanService {
    @Value("${basepacke.base-pack}")
    private String pack;

    @Autowired
    private PermissionMapper mapper;
//    @Override
//    public void scan() {
//    System.out.println(pack);
//        mapper.deleteAll();
//
//        //拿到所有的包
//        List<Class> allClassName = ClassUtils.getAllClassName(pack);
//    System.out.println(allClassName);
//
//        //获取所有Controller
//        //判断是否有自定义注解
//        for (Class clazz : allClassName) {
//            //获取类上的自定义注解
//            PermissionAnnotation annotation = (PermissionAnnotation)clazz.getAnnotation(PermissionAnnotation.class);
//
//            //获取controller 的名字
//            String name = clazz.getSimpleName();
//
//            // 获取类上的RequestMapping  RequestMapping
//            RequestMapping annotation2 = (RequestMapping)clazz.getAnnotation(RequestMapping.class);
//            String[] value = annotation2.value();//获取类上的url
//             System.out.println("获取类上的url:"+ Arrays.toString(value));
//            Permission parent = new Permission();  //  new 一个permission对象
//            System.out.println("annotation.name("+annotation.name());
//            parent.setName(annotation.name());  //annotation.name()是这个controller的上自定义的注解的名字
//            parent.setDescs(annotation.descs());
//            parent.setSn(name);  //这个name是  clazz.getSimpleName();  controller的名字
//            parent.setUrl(annotation2.value()[0]);  // 类上的RequestMapping 的url
////              System.out.println("parent:"+parent);
//              System.out.println("============================");
//
//
//            if (Objects.isNull(annotation)){
//                continue;//如果这个类上没有自定义注解 跳出这个循环
//            }
//
//
//
//            //拿到的是有方法的
//            Method[] methods = clazz.getMethods();
//            for (Method method : methods) {
//                //判断方法是否有自定义注解
//                PermissionAnnotation annotation1 = method.getAnnotation(PermissionAnnotation.class);
//                if (Objects.isNull(annotation1)) {
//                    continue;
//                }
//                // name descs url sn  parent
//                System.out.println("注解的name："+annotation1.name());
//                System.out.println("注解的descs"+annotation1.descs());
//
//                //方法上的url
//                String methodUrl = getMethodUrl(method);
//                System.out.println("methodUrl:"+methodUrl);
//
//                //获取的方法的名字
//                String methodName = method.getName();
//
//        // 打印类名加方法名
//        System.out.println("类名+方法名"+name+":"+methodName);
//
//                System.out.println("===================");
//                //封装对象
//                Permission permission = new Permission();
//                permission.setName(annotation1.name());
//                permission.setDescs(annotation1.descs());
//                permission.setSn(name+":"+method.getName());
//                permission.setUrl(parent.getUrl()+getMethodUrl(method));
//                permission.setParent(parent);
//                System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++");
//                System.out.println("+++++:"+parent);
//                System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++");
////                System.out.println(permission);
//
//                mapper.insert(permission);
//            }
//
//        }
//
//    }
//        // 获取方法上的url
//    public String getMethodUrl(Method method) {
//        String methodUrl = "";
//        // 取枚举中定义的所有的请求类型
//        RequestTypeEnum[] requestTypeEnums = RequestTypeEnum.values();
//        for (RequestTypeEnum typeEnum : requestTypeEnums) {
//            // 根据枚举中的不同的请求类型的class获取该类型对应的注解对象
//            Annotation annotation = method.getAnnotation(typeEnum.getRequestType());
//            // 如果该请求类型注解不存在就跳过
//            if(Objects.isNull(annotation)){
//                continue;
//            }
//            try {
//                // 如果该请求类型注解存在,就获取它里面的value方法
//                Class<? extends Annotation> aClass = annotation.annotationType();
//                Method annotationMethod = aClass.getMethod("value");
//                // 通过invoke调用该对象的value方法,获取结果
//                // 反射执行 方法 方法名.invoke(对象)
//                String[] value = (String[]) annotationMethod.invoke(annotation);
//                // 如果value不为空且长度大于0,就赋值给methodUrl,并跳出循环
//                if(value != null && value.length > 0){
//                    methodUrl = value[0];
//                    break;
//                }
//            }catch (Exception e) {
//                e.printStackTrace();
//                continue;
//            }
//        }
//        return methodUrl;
//    }

    @Override
    public void scan() {
        mapper.deleteAll();
        // 1.拿到所有的包
        List<Class> allClassName = ClassUtils.getAllClassName(pack);
        System.out.println(allClassName);

        // 2.获取所有的Controller
        // 判断是否有自定义注解
        for (Class clazz: allClassName) {
            // 获取类上是否有 自定义注解
            PermissionAnnotation annotation = (PermissionAnnotation)clazz.getAnnotation(PermissionAnnotation.class);
            // 获取类上的RequestMapping

            RequestMapping annotation2 = (RequestMapping)clazz.getAnnotation(RequestMapping.class);
            if (Objects.isNull(annotation)){
                continue;
            }
            String name = clazz.getSimpleName();
            String[] value = annotation2.value();
            Permission parent = new Permission();
            parent.setName(annotation.name());
            parent.setDescs(annotation.descs());
            parent.setSn(name);
            parent.setUrl(annotation2.value()[0]);
            mapper.insert(parent);
            System.out.println("类上的url:" + Arrays.toString(value));
            if (Objects.isNull(annotation)){
                continue;
            }

            // 3. 拿到是有的方法
            Method[] methods = clazz.getMethods();
            for (Method method:methods) {
                // 判断方法是否有自定义注解
                PermissionAnnotation annotation1 = method.getAnnotation(PermissionAnnotation.class);
                if (Objects.isNull(annotation1)){
                    continue;
                }

                // name descs url sn  parent
//                封装对象
                Permission permission = new Permission();
                permission.setName(annotation1.name());
                permission.setDescs(annotation1.descs());
                permission.setSn(name+":"+method.getName());
                permission.setUrl(parent.getUrl()+getMethodUrl(method));
                permission.setParent(parent);

                // 入库
                mapper.insert(permission);
            }

        }

    }

    public String getMethodUrl(Method method){
        String methodUrl = "";
        // 取枚举中定义的所有的请求类型
        RequestTypeEnum[] requestTypeEnums = RequestTypeEnum.values();
        for (RequestTypeEnum typeEnum : requestTypeEnums) {
            // 根据枚举中的不同的请求类型的class获取该类型对应的注解对象
            Annotation annotation = method.getAnnotation(typeEnum.getRequestType());
            // 如果该请求类型注解不存在就跳过
            if(Objects.isNull(annotation)){
                continue;
            }
            try {
                // 如果该请求类型注解存在,就获取它里面的value方法
                Class<? extends Annotation> aClass = annotation.annotationType();
                Method annotationMethod = aClass.getMethod("value");
                // 通过invoke调用该对象的value方法,获取结果
                // 反射执行 方法 方法名.invoke(对象)
                String[] value = (String[]) annotationMethod.invoke(annotation);
                // 如果value不为空且长度大于0,就赋值给methodUrl,并跳出循环
                if(value != null && value.length > 0){
                    methodUrl = value[0];
                    break;
                }
            }catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
        return methodUrl;

    }
}
